package models

import (
	"gorm.io/gorm"
)

type CouponRecord struct {
	Model

	UserId string `json:"user_id" gorm:"not null; index:idx_coupon_records_user_id_coupon_meta_id,priority:1"`
	//CouponMeta   CouponMeta `gorm:"ForeignKey:CouponMetaID; AssociationForeignKey:ID"`
	CouponMetaID int64 `json:"coupon_meta_id" gorm:"not null; index:idx_coupon_records_user_id_coupon_meta_id,priority:2"`

	Status int64 `json:"status" gorm:"not null"`
}

// AddCouponRecord Add a CouponRecord
func AddCouponRecord(data map[string]interface{}) error {
	couponRecord := CouponRecord{
		UserId:       data["user_id"].(string),
		CouponMetaID: data["coupon_meta_id"].(int64),
		Status:       data["status"].(int64),
	}

	if err := db.Create(&couponRecord).Error; err != nil {
		return err
	}

	return nil
}

// EditCouponRecord modify a single CouponRecord by id
func EditCouponRecordByID(id int64, data interface{}) error {
	if err := db.Model(&CouponRecord{}).Where(map[string]interface{}{"id": id, "deleted_on": 0}).Updates(data).Error; err != nil {
		return err
	}

	return nil
}

// EditCouponRecord modify a single CouponRecord by constraints
func EditCouponRecord(maps interface{}, data interface{}) error {
	if err := db.Model(&CouponRecord{}).Where(maps).Updates(data).Error; err != nil {
		return err
	}

	return nil
}

// DeleteCouponRecord delete a CouponRecord by id
func DeleteCouponRecordByID(id int64) error {
	if err := db.Where(map[string]interface{}{"id": id}).Delete(&CouponRecord{}).Error; err != nil {
		return err
	}

	return nil
}

// DeleteCouponRecord delete a CouponRecord by constraints
func DeleteCouponRecord(maps interface{}) error {
	if err := db.Where(maps).Delete(&CouponRecord{}).Error; err != nil {
		return err
	}

	return nil
}

// ExistCouponRecordByID checks if an CouponRecord exists by id
func ExistCouponRecordByID(id int64) (bool, error) {
	var couponRecord CouponRecord
	err := db.Select("id").Where(map[string]interface{}{"id": id, "deleted_on": 0}).First(&couponRecord).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return false, err
	}

	if couponRecord.ID > 0 {
		return true, nil
	}

	return false, nil
}

// ExistCouponRecord checks if an CouponRecord exists by constraints
func ExistCouponRecord(maps interface{}) (bool, error) {
	var couponRecord CouponRecord
	err := db.Select("id").Where(maps).First(&couponRecord).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return false, err
	}

	if couponRecord.ID > 0 {
		return true, nil
	}

	return false, nil
}

// GetCouponRecords gets a list of CouponRecords based on paging and constraints
func GetCouponRecords(pageNum int, pageSize int, maps interface{}) ([]CouponRecord, error) {
	var (
		couponRecords []CouponRecord
		err           error
	)

	if pageNum > 0 && pageSize > 0 {
		err = db.Where(maps).Find(&couponRecords).Offset(pageNum).Limit(pageSize).Error
	} else {
		err = db.Where(maps).Find(&couponRecords).Error
	}

	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	return couponRecords, nil
}

// GetCouponRecordTotal counts the total number of CouponRecords based on the constraint
func GetCouponRecordTotal(maps interface{}) (int64, error) {
	var count int64
	if err := db.Model(&CouponRecord{}).Where(maps).Count(&count).Error; err != nil {
		return 0, err
	}

	return count, nil
}

// CleanAllCouponRecords clear all CouponRecord
func CleanAllCouponRecords() (bool, error) {
	if err := db.Unscoped().Not(map[string]interface{}{"deleted_on": 0}).Delete(&CouponRecord{}).Error; err != nil {
		return false, err
	}

	return true, nil
}
